import React from "react";
import {
    formatDeviationColor,
    formatFileSize,
    formatStatusColor,
    getIconByData,
    getObjByRule,
    isArray,
    isObject
} from "@core/utils";
import dayjs from "dayjs";
import GlobalIcon from "../GlobalIcon.tsx";
import {getLanguageById, getLocale} from "../../../i18n/i18n.tsx";
import Config from "../../Config.tsx";
import CTableOptBtn from "./CTableOptBtn.tsx";
import {Progress} from "antd";
import CTableLink from "./CTableLink.tsx";
import CTablePreview from "./CTablePreview.tsx";
import {useTranslation} from "react-i18next";
import {previewFile} from "../../services/PreviewService.tsx";
import CTableFileList from "./CTableFileList.tsx";
import {validFun} from "../../utils";

let CTableComponents: any = {
    defaultValue: function (props: any) {
        return props.value
    },
    dateShow: function ({value, renderProps = {}}: {
        value: any,
        renderProps: any
    }) {
        const {type = "date"}: { type: "time" | "date" | "week" | "month" | "quarter" | "year" } = renderProps;
        return value ? dayjs(value).format(Config.dateFormat[type]) : value;
    },
    textOverflow: function (props: any) {
        return <div className="col-text-a-line-show" title={props.value}>
            {props.value}
        </div>
    },
    iconShow: function (props: any) {
        const {data, value, renderProps = {}}: {
                data: any,
                value: string,
                renderProps: any
            } = props,
            {iconKey, format}: {
                iconKey: string,
                format: any
            } = renderProps,
            {icon}: {
                icon: any
            } = iconKey ? {icon: getIconByData(iconKey, data)} : (format ? getObjByRule(data, format, true) : {icon: ""});
        return (
            <div>
                {icon ? <GlobalIcon style={{marginRight: 2}} name={icon}/> : null}
                <span title={value}>{value}</span>
            </div>
        )
    },
    progressShow: function ({value, renderProps = {}}: { value: number, renderProps: any }) {
        const {type = "line"}: { type: "line" | "circle" } = renderProps;
        let props: any = {};
        if (type === "line") {
            props = {
                size: "small"
            }
        } else {
            props = {
                size: 21,
                strokeWidth: 4
            }
        }
        return (
            <Progress type={type} percent={value} {...props} className="sf_core_table_progress"/>
        )
    },
    statusShow: function ({value}: { value: string }) {
        const style: any = formatStatusColor(value)
        return (<span>
            <span style={{
                width: 10,
                height: 10,
                borderRadius: 20,
                backgroundColor: style.backgroundColor,
                boxShadow: "0 0 0 2px #eee",
                display: "inline-block",
                marginRight: 10
            }}></span>
            <span>{value}</span>
        </span>)
    },
    deviationShow: function ({value}: { value: string }) {
        const {t} = useTranslation();
        const style: any = formatDeviationColor(value)
        const projectDeviation: any = {
            red: t("redLight"),
            yellow: t("yellowLight"),
            green: t("greenLight")
        }
        return (<span style={{
            backgroundColor: style.backgroundColor,
            color: style.color,
            padding: "2px 10px",
            borderRadius: 20
        }}>{projectDeviation[value]}</span>)
    },
    preShow: function (props: any) {
        return <pre>{props.value}</pre>;
    },
    boolYn: function (props: any) {
        return props.value ? (props.value == true ? getLanguageById('yes') : getLanguageById('no')) : ''
    },
    multiValueShow: function ({value, renderProps = {}}: { value: string[], renderProps: any }) {
        const {showNumber = false}: { showNumber: boolean } = renderProps;
        let text: string | string[] = value;
        if (isArray(value)) {
            if (showNumber) {
                text = value.map((n: string, i: number) => {
                    return (i + 1) + "." + n
                })
            }
            text = text.join(",")
        }
        return <div className="col-text-a-line-show" title={text}>
            {text}
        </div>;
    },
    parsingHtml: function (props: any) {
        let dom = document.createElement("div");
        dom.innerHTML = props.value;
        return dom.innerText;
    },
    fileSize: function (props: any) {
        return formatFileSize(props.value);
    },
    optBtn: function ({data, renderProps = {}, ds}: {
        data: any,
        renderProps: any,
        ds: any
    }) {
        return (<CTableOptBtn
            node={data}
            ds={ds}
            {...renderProps}
        />)
    },
    txtShow: function ({value, data = {}}: { value: string, data: any }) {
        return (
            <div className="sf_core_drawer_info_link">
                   <span className="sf_core_drawer_info_link_value" onClick={() => {
                       previewFile({
                           id: data.id,
                           extName: "txt",
                           file: value
                       }, {isShowVersion: false})
                   }}>{value}</span>
            </div>
        )
    },
    fileListShow: function ({value, data = {}, renderProps = {}}) {
        const {modalProps = {}, rowKey, menuId = "", width} = renderProps;
        return (
            <CTableFileList
                width={width}
                menuId={menuId}
                rowKey={rowKey}
                modalProps={modalProps}
                data={data}
                value={value}
            />
        )
    },
    previewShow: function ({data, value, renderProps = {}}: {
        data: any,
        value: string,
        renderProps: any
    }) {
        const {
            fileIdField,
            suffixField,
            linkFun,
            linkComProps
        }: {
            fileIdField: string,
            suffixField: string,
            linkFun: string,
            linkComProps: any
        } = renderProps;

        return (
            <CTablePreview
                value={value}
                data={data}
                fileIdField={fileIdField}
                suffixField={suffixField}
                linkFun={linkFun}
                linkComProps={linkComProps}
            />
        )
    },
    workspaceShow: function ({data, value, renderProps = {}, ds = {}}: {
        data: any,
        value: any,
        renderProps: any,
        ds: any
    }) {
        let {
                url,
                defaultValue,
                titleKey,
                datasetIdField,
                fileIdField,
                suffixField,
                fromObjectIdField,
                openMode = "split",
                format,
                otherParams,
                modalProps = {},
                objectTypeId,
                objectStatusId,
                linkParams = {},
                icon = "iconId",
                clickCheck = true,
                isShowLink = true,
                linkFun,
                linkComProps,
                validObj
            }: {
                url: string,
                defaultValue: string,
                datasetIdField: string,
                fileIdField: string,
                suffixField: string,
                fromObjectIdField: string,
                titleKey: string,
                openMode: "split" | "tab" | "drawer" | "preview",
                format: any,
                otherParams: any,
                modalProps: any,
                objectTypeId: string,
                objectStatusId: string,
                linkParams: any,
                icon: string,
                isShowLink: boolean,
                clickCheck: boolean,
                linkFun: string,
                linkComProps: any,
                validObj: any
            } = renderProps,
            {id, name, typeId, statusId} = format && isObject(format) ? getObjByRule(data, {
                id: "id",
                name: "zhCn|usEn|ptBr",
                typeId: objectTypeId || data.type || data.id?.slice(0, 4),
                statusId: objectStatusId !== undefined ? objectStatusId : (data.statusId || 0),
                ...format
            }, true) : {
                id: data.id,
                name: getLocale(data.nameCn, data.nameEn),
                typeId: objectTypeId || data.type || data.id?.slice(0, 4),
                statusId: objectStatusId !== undefined ? objectStatusId : (data.statusId || 0),
            },
            queryParams = otherParams ? getObjByRule(data, otherParams) : {};
        const {getLinkParams}: { getLinkParams: any } = ds;
        if (getLinkParams) {
            linkParams = {
                ...linkParams,
                ...getLinkParams(data, renderProps)
            }
        }
        value = value && value.indexOf("-bdmsChange") !== -1 ? value.split("-bdmsChange")[0] : value;
        if (validObj && !validFun(data, validObj)) {
            return <span>{value}</span>
        }
        return (<CTableLink
            clickCheck={clickCheck}
            value={value || defaultValue}
            openMode={openMode}
            data={data}
            datasetIdField={datasetIdField}
            fileIdField={fileIdField}
            suffixField={suffixField}
            fromObjectIdField={fromObjectIdField}
            icon={icon}
            url={url}
            titleKey={titleKey}
            objectId={id}
            objectName={name}
            objectTypeId={typeId}
            objectStatusId={statusId}
            queryParams={queryParams}
            isShowLink={isShowLink}
            linkFun={linkFun}
            linkComProps={linkComProps}
            linkParams={linkParams}
            modalProps={modalProps}
            ds={ds}
        />)
    }
};

// @ts-ignore
const setTableCom: Function = (field: string, fn: any) => {
    CTableComponents[field] = fn;
};

// @ts-ignore
const getTableCom: Function = (field: string) => {
    return CTableComponents[field] || CTableComponents["defaultValue"];
};

// @ts-ignore
const getTableComAll: Function = (newTableCom: any) => {
    if (newTableCom && isObject(newTableCom)) {
        for (let key: string in newTableCom) {
            setTableCom(key, newTableCom[key])
        }
    }
    return CTableComponents;
};
export {
    setTableCom,
    getTableCom,
    getTableComAll
};
